package main

import (
	"bufio"
	"fmt"
	"net"
)

func main() {
	listener, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println(err)
	}

	go broadcast()

	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println(err)
			continue
		}
		go handleConn(conn)
	}
}

type client struct {
	name string
	ch   chan<- string
}

var (
	entering = make(chan client)
	leaving  = make(chan client)
	messages = make(chan string)
)

func broadcast() {
	clients := make(map[client]bool)
	for {
		select {
		case msg := <-messages:
			for cli := range clients {
				cli.ch <- msg
			}
		case cli := <-entering:
			for other := range clients {
				if other != cli {

				}
			}
			clients[cli] = true
		case cli := <-leaving:
			delete(clients, cli)
		}

	}
}

func handleConn(r net.Conn) {
	ch := make(chan string)
	go clientWriter(r, ch)

	who := r.RemoteAddr().String()

	ch <- "You are " + who
	entering <- ch

	messages <- who + " has arrived"

	input := bufio.NewScanner(r)
	for !input.Scan() {
		line := input.Text()
		messages <- line
	}

	leaving <- ch
	messages <- who + " has left"

	r.Close()
}

func clientWriter(r net.Conn, ch <-chan string) {
	for msg := range ch {
		fmt.Println(r, msg)
	}
}
